//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "MakeCPPClass.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include <iostream>
#include <fstream>
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#define SIZE_READ 10000
#define COMMENT_SEPARATOR "//---------------------------------------------------------------------------------------------------------------------------------------------------------//\n"
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
using namespace std;
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
namespace MakeClassSpace {
  
  bool EqualInclude (TNode <String>* include, void* ref) {

    return (!strcmp(include->Info()->Out(), ((String*)ref)->Out()))?true:false;

  }
  
  bool AscendentInclude(String* include, void* ref) {

    return (strcmp(include->Out(), ((String*)ref)->Out()) < 0)?true:false;

  }
  
  bool AscendentByAttributeType(Attribute* attribute, void* ref) {

    return (strcmp(attribute->AttributeType()->Out(), ((Attribute*)ref)->AttributeType()->Out()) < 0)?true:false;

  }
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
Attribute::Attribute () {
  
  this->attributeName     = new String ();
  this->attributeScope    = '-';
  this->attributeType     = new String ();
  this->attributeIncludes = new TListE <String> ();
  this->toString          = new String ();

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
Attribute::Attribute (const Attribute& attribute) {

  this->attributeName     = new String (attribute.attributeName);
  this->attributeScope    = attribute.attributeScope;
  this->attributeType     = new String (attribute.attributeType);
  this->attributeIncludes = new TListE <String> (attribute.attributeIncludes);
  this->toString          = new String ();

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
Attribute::Attribute (const Attribute* attribute) {

  this->attributeName     = new String (attribute->attributeName);
  this->attributeScope    = attribute->attributeScope;
  this->attributeType     = new String (attribute->attributeType);
  this->attributeIncludes = new TListE <String> (attribute->attributeIncludes);
  this->toString          = new String ();

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
Attribute::~Attribute () {
  
  if (this->attributeName)      delete this->attributeName;
  if (this->attributeType)      delete this->attributeType;
  if (this->attributeIncludes)  delete this->attributeIncludes;
  if (this->toString)           delete this->toString;
    
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void Attribute::AttributeName (String* attributeName) {
  
  if (attributeName) 
    this->attributeName->In(attributeName);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void Attribute::AttributeScope (char attributeScope) {
  
  this->attributeScope = (attributeScope == '-' || attributeScope == '+' || attributeScope == '*')?attributeScope:'-';
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void Attribute::AttributeType (String* attributeType) {
  
  if (attributeType) 
    this->attributeType->In(attributeType);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void Attribute::AttributeIncludes (TListE <String>* attributeIncludes) {
  
  if (attributeIncludes)
    *(this->attributeIncludes) = *attributeIncludes;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* Attribute::AttributeName (void) {
  
  return this->attributeName;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
char Attribute::AttributeScope (void) {
  
  return this->attributeScope;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* Attribute::AttributeType (void) {
  
  return this->attributeType;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
TListE <String>* Attribute::AttributeIncludes (void) {
  
  return this->attributeIncludes;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool Attribute::LoadAttributeInfo (String* line) {
  
  return (line)?this->LoadAttributeInfo(line->Out()):false;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool Attribute::LoadAttributeInfo (char* line) {
  
  //-Attribute: AttributeName (Type[@Include;...])

  if (!line || !strlen(line))
    return false;
  
  char* parts = strtok(line, ":@;()");
  if (!parts) 
    return false;
  this->attributeScope = parts[0];
  
  parts = strtok(NULL, ":@;() ");
  if (!parts) 
    return false;
  this->attributeName->In(parts);
  
  parts = strtok(NULL, "@;()");
  if (!parts) 
    return false;
  this->attributeType->In(parts);

  parts = strtok(NULL, "@;()");
  while (parts) {
    this->attributeIncludes->Add(new String(parts));
    parts = strtok(NULL, "@;()");
  }
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* Attribute::GetAttributeDefinition (int weightAttributeType) {
  
  this->toString->In("");
  
  if (!this->attributeType || !this->attributeType->Length() ||
      !this->attributeName || !this->attributeName->Length())
    return NULL;
  
  char format [SIZE_READ];
  char buffer [SIZE_READ];
  
  sprintf(format, "%%-%ds %%s;", weightAttributeType);
  sprintf(buffer, format, this->attributeType->Out(), this->attributeName->Out());
  
  this->toString->In(buffer);
  
  return this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* Attribute::GetParameterDefinition (void) {
  
  this->toString->In("");
  
  if (!this->attributeType || !this->attributeType->Length() ||
      !this->attributeName || !this->attributeName->Length())
    return NULL;
  
  char buffer [SIZE_READ];
  
  sprintf(buffer, "%s %s", this->attributeType->Out(), this->attributeName->Out());
  
  this->toString->In(buffer);
  
  return this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* Attribute::GetIncludes (void) {
  
  this->toString->In("");
  
  if (!this->attributeIncludes)
    return NULL;
  
  char buffer [SIZE_READ];
  
  this->attributeIncludes->SetInitial();
  while (this->attributeIncludes->SetNext()) {
    sprintf(buffer, "#include \"%s\"\n", this->attributeIncludes->GetCurrent()->Out());
    this->toString->Add(buffer);
  }
  
  return this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* Attribute::GetAttributeSetMethodDefinition (int weightAttributeType) {
  
  this->toString->In("");
  
  if (!this->attributeType || !this->attributeType->Length() ||
      !this->attributeName || !this->attributeName->Length())
    return NULL;
  
  char format [SIZE_READ];
  char buffer [SIZE_READ];
  char voidText [] = "void";
  
  sprintf(format, "%%-%ds %%c%%s (%%s %%c%%s);", weightAttributeType);
  sprintf(buffer, format, voidText, toupper(this->attributeName->Out()[0]), this->attributeName->Out() + 1, this->attributeType->Out(), tolower(this->attributeName->Out()[0]), this->attributeName->Out() + 1);
  
  this->toString->In(buffer);
  
  return this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* Attribute::GetAttributeGetMethodDefinition (int weightAttributeType) {
  
  this->toString->In("");
  
  if (!this->attributeType || !this->attributeType->Length() ||
      !this->attributeName || !this->attributeName->Length())
    return NULL;
  
  char format [SIZE_READ];
  char buffer [SIZE_READ];
  
  sprintf(format, "%%-%ds %%c%%s (void);", weightAttributeType);
  sprintf(buffer, format, this->attributeType->Out(), toupper(this->attributeName->Out()[0]), this->attributeName->Out() + 1);
  
  this->toString->In(buffer);
  
  return this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* Attribute::GetAttributeSetMethodDeclaration (String* className) {
  
  this->toString->In("");
  
  if (!this->attributeType || !this->attributeType->Length() ||
      !this->attributeName || !this->attributeName->Length() ||
      !className           || !className->Length())
    return NULL;
  
  
  char body [SIZE_READ];
  
  if (this->attributeType->Contain("*"))
    sprintf(body, "  if (%s)\n    *(this->%s) = *%s;", this->attributeName->Out(), this->attributeName->Out(), this->attributeName->Out());
  else
    sprintf(body, "  this->%s = %s;", this->attributeName->Out(), this->attributeName->Out());

  char buffer [SIZE_READ];
  
  sprintf(buffer, "void %s::%c%s (%s %c%s) {\n\n%s\n\n}", className->Out(), toupper(this->attributeName->Out()[0]), this->attributeName->Out() + 1, this->attributeType->Out(), tolower(this->attributeName->Out()[0]), this->attributeName->Out() + 1, body);
  
  this->toString->In(buffer);
  
  return this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* Attribute::GetAttributeGetMethodDeclaration (String* className) {
  
  this->toString->In("");
  
  if (!this->attributeType || !this->attributeType->Length() ||
      !this->attributeName || !this->attributeName->Length() ||
      !className           || !className->Length())
    return NULL;
  
  char buffer [SIZE_READ];
  
  sprintf(buffer, "%s %s::%c%s (void) {\n\n  return this->%s;\n\n}", this->attributeType->Out(), className->Out(), toupper(this->attributeName->Out()[0]), this->attributeName->Out() + 1, this->attributeName->Out());
  
  this->toString->In(buffer);
  
  return this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
Attribute Attribute::operator= (const Attribute& attribute) {

  this->attributeName->In(attribute.attributeName);
  this->attributeScope       = attribute.attributeScope;
  this->attributeType->In(attribute.attributeType);
  *(this->attributeIncludes) = *(attribute.attributeIncludes);
  
  return *this;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
Method::Method () {
  
  this->methodName       = new String ();
  this->methodScope      = '-';
  this->methodReturn     = new String ();
  this->methodParameters = new TListE <Attribute> ();
  this->methodIncludes   = new TListE <String> ();
  this->toString         = new String ();

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
Method::Method (const Method& method) {

  this->methodName       = new String (method.methodName);
  this->methodScope      = method.methodScope;
  this->methodReturn     = new String (method.methodReturn);
  this->methodParameters = new TListE <Attribute> (method.methodParameters);
  this->methodIncludes   = new TListE <String> (method.methodIncludes);
  this->toString         = new String ();

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
Method::Method (const Method* method) {

  this->methodName       = new String (method->methodName);
  this->methodScope      = method->methodScope;
  this->methodReturn     = new String (method->methodReturn);
  this->methodParameters = new TListE <Attribute> (method->methodParameters);
  this->methodIncludes   = new TListE <String> (method->methodIncludes);
  this->toString         = new String ();

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
Method::~Method () {
  
  if (this->methodName)        delete this->methodName;
  if (this->methodReturn)      delete this->methodReturn;
  if (this->methodParameters)  delete this->methodParameters;
  if (this->methodIncludes)    delete this->methodIncludes;
  if (this->toString)          delete this->toString;
    
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void Method::MethodName (String* methodName) {
  
  if (methodName)
    this->methodName->In(methodName);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void Method::MethodScope (char methodScope) {
  
  this->methodScope = (methodScope == '-' || methodScope == '+' || methodScope == '*')?methodScope:'-';
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void Method::MethodReturn (String* methodReturn) {
  
  if (methodReturn)
    this->methodReturn->In(methodReturn);
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void Method::MethodParameters (TListE <Attribute>* methodParameters) {
  
  if (methodParameters)
    *(this->methodParameters) = *methodParameters;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void Method::MethodIncludes (TListE <String>* methodIncludes) {
  
  if (methodIncludes)
    *(this->methodIncludes) = *methodIncludes;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* Method::MethodName (void) {
  
  return this->methodName;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
char Method::MethodScope (void) {
  
  return this->methodScope;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* Method::MethodReturn (void) {
  
  return this->methodReturn;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
TListE <Attribute>* Method::MethodParameters (void) {
  
  return this->methodParameters;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
TListE <String>* Method::MethodIncludes (void) {
  
  return this->methodIncludes;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool Method::LoadMethodInfo (String* line) {
  
  return (line)?this->LoadMethodInfo(line->Out()):false;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool Method::LoadMethodInfo (char* line) {
  
  //-Method: MethodName (Type{ParameterName};...) = Type [@Include;...]

  if (!line || !strlen(line))
    return false;
  
  char *buffer1 = strtok(line, "=");
  if (!buffer1) 
    return false;

  char *buffer2 = strtok(NULL, "=");
  if (!buffer2) 
    return false;

  char* parts = strtok(buffer1, ":");
  if (!parts) 
    return false;
  this->methodScope = parts[0];

  parts = strtok(NULL, ": ");
  if (!parts) 
    return false;
  this->methodName->In(parts);

  TListE <String>* parameters = new TListE <String> ();

  parts = strtok(NULL, ";()");
  while (parts) {
    parameters->Add(new String(parts));
    parts = strtok(NULL, ";()");
  }
  
  parameters->SetInitial();
  while (parameters->SetNext()) {
    
    Attribute* newAttribute = new Attribute ();
    
    parts = strtok(parameters->GetCurrent()->Out(), "{}");
    if (!parts) {
      if (newAttribute) delete newAttribute;
      continue;
    }
    newAttribute->AttributeType()->In(parts);

    parts = strtok(NULL, "{}");
    if (!parts) {
      if (newAttribute) delete newAttribute;
      continue;
    }
    newAttribute->AttributeName()->In(parts);

    this->methodParameters->Add(newAttribute);
    
  }
  
  if (parameters) delete parameters;
  
  parts = strtok(buffer2, " @;");
  if (!parts) 
    return false;
  this->methodReturn->In(parts);

  parts = strtok(NULL, "@;");
  while (parts) {
    this->methodIncludes->Add(new String(parts));
    parts = strtok(NULL, "@;");
  }

  return true;
 
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* Method::GetMethodDefinition (int weightMethodType) {
  
  this->toString->In("");
  
  if (!this->methodReturn || !this->methodReturn->Length() ||
      !this->methodName   || !this->methodName->Length()   ||
      !this->methodParameters)
    return NULL;
  
  char format [SIZE_READ];
  char buffer [SIZE_READ];
  
  sprintf(format, "%%-%ds %%s", weightMethodType);
  sprintf(buffer, format, this->methodReturn->Out(), this->methodName->Out());
  this->toString->In(buffer);
  
  this->toString->Add(" (");
  
  if (!this->methodParameters->Length())
    this->toString->Add("void");
  else {
    
    bool start = true;
    
    this->methodParameters->SetInitial();
    while (this->methodParameters->SetNext()) {
      
      if (!start)
        this->toString->Add(", ");
      
      this->toString->Add(this->methodParameters->GetCurrent()->AttributeType()->Out());
      this->toString->Add(" ");
      this->toString->Add(this->methodParameters->GetCurrent()->AttributeName()->Out());
      
      start = false;
      
    }
    
  }
  
  this->toString->Add(");");
  
  return this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* Method::GetMethodDeclaration (String* methodClass) {
  
  this->toString->In("");
  
  if (!this->methodReturn || !this->methodReturn->Length() ||
      !this->methodName   || !this->methodName->Length()   ||
      !this->methodParameters)
    return NULL;
  
  char buffer [SIZE_READ];
  
  sprintf(buffer, "%s %s::%s", this->methodReturn->Out(), methodClass->Out(), this->methodName->Out());
  this->toString->In(buffer);
  
  this->toString->Add(" (");
  
  if (!this->methodParameters->Length())
    this->toString->Add("void");
  else {
    
    bool start = true;
    
    this->methodParameters->SetInitial();
    while (this->methodParameters->SetNext()) {
      
      if (!start)
        this->toString->Add(", ");
      
      this->toString->Add(this->methodParameters->GetCurrent()->AttributeType()->Out());
      this->toString->Add(" ");
      this->toString->Add(this->methodParameters->GetCurrent()->AttributeName()->Out());
      
      start = false;
      
    }
    
  }
  
  this->toString->Add(") {\n\n\n}");
  
  return this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* Method::GetIncludes (void) {
  
  this->toString->In("");
  
  if (!this->methodIncludes)
    return NULL;
  
  char buffer [SIZE_READ];
  
  this->methodIncludes->SetInitial();
  while (this->methodIncludes->SetNext()) {
    sprintf(buffer, "#include \"%s\"\n", this->methodIncludes->GetCurrent()->Out());
    this->toString->Add(buffer);
  }
  
  return this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
Method Method::operator= (const Method& method) {
  
  this->methodName->In(method.methodName);
  this->methodScope         = method.methodScope;
  this->methodReturn->In(method.methodReturn);
  *(this->methodParameters) = *(method.methodParameters);
  *(this->methodIncludes)   = *(method.methodIncludes);

  return *this;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
MakeCPPClass::MakeCPPClass () {
  
  this->className         = new String ();
  this->classInheritance  = new TListE <String> ();
  this->classAttributes   = new TListE <Attribute> ();
  this->classMethods      = new TListE <Method> ();
  this->toString          = new String ();
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
MakeCPPClass::MakeCPPClass (const MakeCPPClass& makeCPPClass) {
  
  this->className         = new String (makeCPPClass.className);
  this->classInheritance  = new TListE <String> (makeCPPClass.classInheritance);
  this->classAttributes   = new TListE <Attribute> (makeCPPClass.classAttributes);
  this->classMethods      = new TListE <Method> (makeCPPClass.classMethods);
  this->toString          = new String ();
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
MakeCPPClass::MakeCPPClass (const MakeCPPClass* makeCPPClass) {
  
  this->className         = new String (makeCPPClass->className);
  this->classInheritance  = new TListE <String> (makeCPPClass->classInheritance);
  this->classAttributes   = new TListE <Attribute> (makeCPPClass->classAttributes);
  this->classMethods      = new TListE <Method> (makeCPPClass->classMethods);
  this->toString          = new String ();
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
MakeCPPClass::~MakeCPPClass () {
  
  if (this->className)        delete this->className;
  if (this->classInheritance) delete this->classInheritance;
  if (this->classAttributes)  delete this->classAttributes;
  if (this->classMethods)     delete this->classMethods;
  if (this->toString)         delete this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void MakeCPPClass::ClassName (String* className) {
  
  if (className)
    this->className->In(className);
  }
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void MakeCPPClass::ClassInheritance (TListE <String>* classInheritance) {
  
  if (classInheritance)
    *(this->classInheritance) = *classInheritance;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void MakeCPPClass::ClassAttributes (TListE <Attribute>* classAttributes) {
  
  if (classAttributes)
    *(this->classAttributes) = *classAttributes;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void MakeCPPClass::ClassMethods (TListE <Method>* classMethods) {
  
  if (classMethods)
    *(this->classMethods) = *classMethods;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* MakeCPPClass::ClassName (void) {
  
  return this->className;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
TListE <String>* MakeCPPClass::ClassInheritance (void) {
  
  return this->classInheritance;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
TListE <Attribute>* MakeCPPClass::ClassAttributes (void) {
  
  return this->classAttributes;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
TListE <Method>* MakeCPPClass::ClassMethods (void) {
  
  return this->classMethods;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool MakeCPPClass::LoadClassInfo (String* data) {
  
  return (data)?this->LoadClassInfo(data->Out()):false;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool MakeCPPClass::LoadClassInfo (char* data) {

  /*
  Name: ClassName [@inheritance;inheritance]

  +Attribute: AttributeName (Type[@Include;...])
  -Attribute: AttributeName (Type[@Include;...])
  *Attribute: AttributeName (Type[@Include;...])

  +Method: MethodName (Type{ParameterName};...) = Type [@Include;...]
  -Method: MethodName (Type{ParameterName};...) = Type [@Include;...]
  *Method: MethodName (Type{ParameterName};...) = Type [@Include;...]
   */
  
  if (!data || !strlen(data))
    return false;
  
  this->classInheritance->Clear();
  this->classAttributes->Clear();
  this->classMethods->Clear();
  
  TListE <String>*  lines = new TListE <String> ();
  char*             parts = strtok(data, "\n");
  String            line;
  
  while (parts) {
  
    line.In(parts); line.RTrim();
    if (!line.Length()) continue;
    
    lines->Add(new String(parts));
    
    parts = strtok(NULL, "\n");
    
  }
  
  lines->SetInitial();
  while (lines->SetNext()) {
    
    if (!strncmp(lines->GetCurrent()->Out(), "Name:", strlen("Name:"))) {
      
      char buffer [SIZE_READ];
      int  counter = sscanf(lines->GetCurrent()->Out(), "Name: %s", buffer);
      
      if (counter < 1)
        return false;
      
      if (strstr(buffer, "@")) {

        char* parts = strtok(buffer, "@;");
        if (!parts) 
          return false;
        this->className->In(parts);

        parts = strtok(NULL, "@;");
        while (parts) {
          this->classInheritance->Add(new String(parts));
          parts = strtok(NULL, "@;");
        }

      }
      else this->className->In(buffer);
      
    }
    else if (!strncmp(lines->GetCurrent()->Out() + 1, "Attribute:", strlen("Attribute:"))) {
      
      Attribute* newAttribute = new Attribute ();
      
      if (newAttribute->LoadAttributeInfo(lines->GetCurrent()->Out())) this->classAttributes->Add(newAttribute);
      else                                        delete newAttribute;
      
    }
    else if (!strncmp(lines->GetCurrent()->Out() + 1, "Method:", strlen("Method:"))) {
      
      Method* newMethod = new Method ();
      
      if (newMethod->LoadMethodInfo(lines->GetCurrent()->Out())) this->classMethods->Add(newMethod);
      else                                  delete newMethod;
      
    }
    
  }
  
  if (lines) delete lines;
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool MakeCPPClass::ConstructCPPClass (void) {
  
  if (!this->className || !this->className->Length())
    return false;
  
  char buffer [SIZE_READ];
  
  sprintf(buffer, "%s.h", this->className->Out());
  ofstream fileHeader (buffer);
  if (!fileHeader.is_open()) return false;

  sprintf(buffer, "%s.cpp", this->className->Out());
  ofstream fileSource (buffer);
  if (!fileSource.is_open()) { fileHeader.close(); return false; }
  
  fileHeader << this->GetHeaderCPPClass()->Out();
  fileSource << this->GetSourceCPPClass()->Out();
  
  fileHeader.close();
  fileSource.close();
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* MakeCPPClass::GetHeaderCPPClass (void) {
  
  char buffer [SIZE_READ];
  
  this->toString->In("");
  
  this->toString->Add(COMMENT_SEPARATOR);
  this->toString->Add(COMMENT_SEPARATOR);
  
  sprintf(buffer, "#ifndef _%s_h__\n", this->className->Out());
  this->toString->Add(buffer);
  sprintf(buffer, "#define _%s_h__\n", this->className->Out());
  this->toString->Add(buffer);
  
  this->toString->Add(COMMENT_SEPARATOR);
  this->toString->Add(COMMENT_SEPARATOR);
  
  TListE <String>* listIncludes = new TListE <String> ();
  
  if (this->ConstructListIncludes(listIncludes)) {
    
    listIncludes->SetInitial();
    while (listIncludes->SetNext()) {
      sprintf(buffer, "#include <%s>\n", listIncludes->GetCurrent()->Out());
      this->toString->Add(buffer);
    }
    
  }
  
  if (listIncludes) delete listIncludes;

  this->toString->Add(COMMENT_SEPARATOR);
  this->toString->Add(COMMENT_SEPARATOR);
  
  buffer[0] = '\0';
  
  bool start = true;
  
  this->classInheritance->SetInitial();
  while (this->classInheritance->SetNext()) {
    sprintf(buffer, (start)?("%s public %s\0"):("%s, public %s\0"),  buffer, this->classInheritance->GetCurrent()->Out());
    start = false;
  }
  
  if (strlen(buffer)) sprintf(buffer, "class %s : %s { \n\n", this->className->Out(), buffer);
  else                sprintf(buffer, "class %s { \n\n", this->className->Out());
  
  this->toString->Add(buffer);
  
  this->toString->Add("  private:\n\n");
  
  this->classAttributes->QuickSortListByArray(MakeClassSpace::AscendentByAttributeType, NULL);
  
  int lengthLargerAttributeType = 0;
  
  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) 
    lengthLargerAttributeType = (this->classAttributes->GetCurrent()->AttributeType()->Length() > lengthLargerAttributeType)?
                                 this->classAttributes->GetCurrent()->AttributeType()->Length():
                                 lengthLargerAttributeType; 
  
  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) {
    if (this->classAttributes->GetCurrent()->AttributeScope() != '-')
      continue;
    sprintf(buffer, "    %s\n", this->classAttributes->GetCurrent()->GetAttributeDefinition(lengthLargerAttributeType)->Out());
    this->toString->Add(buffer);
  }
  
  this->classMethods->SetInitial();
  while (this->classMethods->SetNext()) {
    if (this->classMethods->GetCurrent()->MethodScope() != '-')
      continue;
    sprintf(buffer, "    %s\n", this->classMethods->GetCurrent()->GetMethodDefinition(lengthLargerAttributeType)->Out());
    this->toString->Add(buffer);
  }
  
  this->toString->Add("\n");

  this->toString->Add("  protected:\n\n");
  
  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) {
    if (this->classAttributes->GetCurrent()->AttributeScope() != '*')
      continue;
    sprintf(buffer, "    %s\n", this->classAttributes->GetCurrent()->GetAttributeDefinition(lengthLargerAttributeType)->Out());
    this->toString->Add(buffer);
  }
  
  this->classMethods->SetInitial();
  while (this->classMethods->SetNext()) {
    if (this->classMethods->GetCurrent()->MethodScope() != '*')
      continue;
    sprintf(buffer, "    %s\n", this->classMethods->GetCurrent()->GetMethodDefinition(lengthLargerAttributeType)->Out());
    this->toString->Add(buffer);
  }
  
  this->toString->Add("\n");

  this->toString->Add("  public:\n\n");
  
  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) {
    if (this->classAttributes->GetCurrent()->AttributeScope() != '+')
      continue;
    sprintf(buffer, "    %s\n", this->classAttributes->GetCurrent()->GetAttributeDefinition(lengthLargerAttributeType)->Out());
    this->toString->Add(buffer);
  }
  
  sprintf(buffer, "    %s ();\n", this->className->Out());
  this->toString->Add(buffer);
  sprintf(buffer, "    %s (const %s&);\n", this->className->Out(), this->className->Out());
  this->toString->Add(buffer);
  sprintf(buffer, "    %s (const %s*);\n", this->className->Out(), this->className->Out());
  this->toString->Add(buffer);
  
  this->toString->Add("\n");

  sprintf(buffer, "    ~%s ();\n", this->className->Out());
  this->toString->Add(buffer);

  this->toString->Add("\n");

  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) {
    if (!strcmp(this->classAttributes->GetCurrent()->AttributeName()->Out(), "toString")) 
      continue;
    sprintf(buffer, "    %s\n", this->classAttributes->GetCurrent()->GetAttributeSetMethodDefinition(lengthLargerAttributeType)->Out());
    this->toString->Add(buffer);
  }
  
  this->toString->Add("\n");
  
  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) {
    if (!strcmp(this->classAttributes->GetCurrent()->AttributeName()->Out(), "toString")) 
      continue;
    sprintf(buffer, "    %s\n", this->classAttributes->GetCurrent()->GetAttributeGetMethodDefinition(lengthLargerAttributeType)->Out());
    this->toString->Add(buffer);
  }
  
  this->toString->Add("\n");

  this->classMethods->SetInitial();
  while (this->classMethods->SetNext()) {
    if (this->classMethods->GetCurrent()->MethodScope() != '+')
      continue;
    sprintf(buffer, "    %s\n", this->classMethods->GetCurrent()->GetMethodDefinition(lengthLargerAttributeType)->Out());
    this->toString->Add(buffer);
  }
  
  this->toString->Add("\n");

  char format [SIZE_READ];
  
  sprintf(format, "    %%-%ds operator= (const %%s& %%c%%s);\n", lengthLargerAttributeType);
  sprintf(buffer, format, this->className->Out(), this->className->Out(), tolower(this->className->Out()[0]), this->className->Out() + 1);
  this->toString->Add(buffer);
  
  this->toString->Add("\n");

  this->toString->Add("};\n");
  this->toString->Add(COMMENT_SEPARATOR);
  this->toString->Add(COMMENT_SEPARATOR);

  this->toString->Add("#endif\n");
  this->toString->Add(COMMENT_SEPARATOR);
  this->toString->Add(COMMENT_SEPARATOR);

  return this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* MakeCPPClass::GetSourceCPPClass (void) {
  
  char format [SIZE_READ];
  char buffer [SIZE_READ];
  
  this->toString->In("");
  
  this->toString->Add(COMMENT_SEPARATOR);
  this->toString->Add(COMMENT_SEPARATOR);
  
  sprintf(buffer, "#include \"%s.h\"\n", this->className->Out());
  this->toString->Add(buffer);
  
  this->toString->Add("\n");

  sprintf(buffer, "#include <stdio.h>\n", this->className->Out());
  this->toString->Add(buffer);
  sprintf(buffer, "#include <stdlib.h>\n", this->className->Out());
  this->toString->Add(buffer);
  sprintf(buffer, "#include <string.h>\n", this->className->Out());
  this->toString->Add(buffer);
  
  this->toString->Add("\n");

  sprintf(buffer, "#include <fstream>\n", this->className->Out());
  this->toString->Add(buffer);
  sprintf(buffer, "#include <iostream>\n", this->className->Out());
  this->toString->Add(buffer);

  this->toString->Add(COMMENT_SEPARATOR);
  this->toString->Add(COMMENT_SEPARATOR);
  
  sprintf(buffer, "using namespace std;\n", this->className->Out());
  this->toString->Add(buffer);

  this->toString->Add(COMMENT_SEPARATOR);
  this->toString->Add(COMMENT_SEPARATOR);

  sprintf(buffer, "#define MAX_SIZE 500000\n", this->className->Out());
  this->toString->Add(buffer);
  
  this->toString->Add(COMMENT_SEPARATOR);
  this->toString->Add(COMMENT_SEPARATOR);
  
  sprintf(buffer, "%s::%s () {\n\n", this->className->Out(), this->className->Out());
  this->toString->Add(buffer);
  
  int lengthLargerAttributeType = 0;
  int lengthLargerAttributeName = 0;
  
  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) {
    lengthLargerAttributeType = (this->classAttributes->GetCurrent()->AttributeType()->Length() > lengthLargerAttributeType)?
                                 this->classAttributes->GetCurrent()->AttributeType()->Length():
                                 lengthLargerAttributeType; 
    lengthLargerAttributeName = (this->classAttributes->GetCurrent()->AttributeName()->Length() > lengthLargerAttributeName)?
                                 this->classAttributes->GetCurrent()->AttributeName()->Length():
                                 lengthLargerAttributeName; 
  }

  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) {
    
    if (strstr(this->classAttributes->GetCurrent()->AttributeType()->Out(), "*")) {
      sprintf(format, "  this->%%-%ds = new %%s ();\n", lengthLargerAttributeType);
      char buffer1 [SIZE_READ];
      strcpy(buffer1, this->classAttributes->GetCurrent()->AttributeType()->Out());
      buffer1[strlen(buffer1) - 1] = '\0';
      sprintf(buffer, format, this->classAttributes->GetCurrent()->AttributeName()->Out(), buffer1);
      this->toString->Add(buffer);
    }
    else if (!strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "int")    || 
             !strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "double") ||
             !strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "float")) {
      sprintf(format, "  this->%%-%ds = 0;\n", lengthLargerAttributeType);
      sprintf(buffer, format, this->classAttributes->GetCurrent()->AttributeName()->Out());
      this->toString->Add(buffer);
    }
    else if (!strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "char")) {
      sprintf(format, "  this->%%-%ds = ' ';\n", lengthLargerAttributeType);
      sprintf(buffer, format, this->classAttributes->GetCurrent()->AttributeName()->Out());
      this->toString->Add(buffer);
    }
    else if (!strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "bool")) {
      sprintf(format, "  this->%%-%ds = true;\n", lengthLargerAttributeType);
      sprintf(buffer, format, this->classAttributes->GetCurrent()->AttributeName()->Out());
      this->toString->Add(buffer);
    }
    
  }
  
  sprintf(buffer, "\n}\n", this->className->Out());
  this->toString->Add(buffer);
  
  this->toString->Add(COMMENT_SEPARATOR);
  this->toString->Add(COMMENT_SEPARATOR);
  
  sprintf(buffer, "%s::%s (const %s& %c%s) {\n\n", this->className->Out(), this->className->Out(), this->className->Out(), tolower(this->className->Out()[0]), this->className->Out() + 1);
  this->toString->Add(buffer);
  
  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) {
    
    if (strstr(this->classAttributes->GetCurrent()->AttributeType()->Out(), "*")) {
      sprintf(format, "  this->%%-%ds = new %%s (%%c%%s.%%s);\n", lengthLargerAttributeType);
      char buffer1 [SIZE_READ];
      strcpy(buffer1, this->classAttributes->GetCurrent()->AttributeType()->Out());
      buffer1[strlen(buffer1) - 1] = '\0';
      sprintf(buffer, format, this->classAttributes->GetCurrent()->AttributeName()->Out(), buffer1, tolower(this->className->Out()[0]), this->className->Out() + 1, this->classAttributes->GetCurrent()->AttributeName()->Out());
      this->toString->Add(buffer);
    }
    else if (!strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "int")    || 
             !strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "double") ||
             !strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "float")  ||
             !strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "char")   ||
             !strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "bool")) {
      sprintf(format, "  this->%%-%ds = %%c%%s.%%s;\n", lengthLargerAttributeType);
      sprintf(buffer, format, this->classAttributes->GetCurrent()->AttributeName()->Out(), tolower(this->className->Out()[0]), this->className->Out() + 1, this->classAttributes->GetCurrent()->AttributeName()->Out());
      this->toString->Add(buffer);
    }
    
  }
  
  sprintf(buffer, "\n}\n", this->className->Out());
  this->toString->Add(buffer);
  
  this->toString->Add(COMMENT_SEPARATOR);
  this->toString->Add(COMMENT_SEPARATOR);
  
  sprintf(buffer, "%s::%s (const %s* %c%s) {\n\n", this->className->Out(), this->className->Out(), this->className->Out(), tolower(this->className->Out()[0]), this->className->Out() + 1);
  this->toString->Add(buffer);
  
  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) {
    
    if (strstr(this->classAttributes->GetCurrent()->AttributeType()->Out(), "*")) {
      sprintf(format, "  this->%%-%ds = new %%s (%%c%%s->%%s);\n", lengthLargerAttributeType);
      char buffer1 [SIZE_READ];
      strcpy(buffer1, this->classAttributes->GetCurrent()->AttributeType()->Out());
      buffer1[strlen(buffer1) - 1] = '\0';
      sprintf(buffer, format, this->classAttributes->GetCurrent()->AttributeName()->Out(), buffer1, tolower(this->className->Out()[0]), this->className->Out() + 1, this->classAttributes->GetCurrent()->AttributeName()->Out());
      this->toString->Add(buffer);
    }
    else if (!strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "int")    || 
             !strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "double") ||
             !strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "float")  ||
             !strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "char")   ||
             !strcmp(this->classAttributes->GetCurrent()->AttributeType()->Out(), "bool")) {
      sprintf(format, "  this->%%-%ds = %%c%%s->%%s;\n", lengthLargerAttributeType);
      sprintf(buffer, format, this->classAttributes->GetCurrent()->AttributeName()->Out(), tolower(this->className->Out()[0]), this->className->Out() + 1, this->classAttributes->GetCurrent()->AttributeName()->Out());
      this->toString->Add(buffer);
    }
    
  }
  
  sprintf(buffer, "\n}\n", this->className->Out());
  this->toString->Add(buffer);
  
  this->toString->Add(COMMENT_SEPARATOR);
  this->toString->Add(COMMENT_SEPARATOR);
  
  sprintf(buffer, "%s::~%s () {\n\n", this->className->Out(), this->className->Out());
  this->toString->Add(buffer);
  
  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) {
    
    if (strstr(this->classAttributes->GetCurrent()->AttributeType()->Out(), "*")) {
      sprintf(format, "  if (this->%%-%ds) delete this->%%s;\n", lengthLargerAttributeName);
      sprintf(buffer, format, this->classAttributes->GetCurrent()->AttributeName()->Out(), this->classAttributes->GetCurrent()->AttributeName()->Out());
      this->toString->Add(buffer);
    }
    
  }
  
  sprintf(buffer, "\n}\n", this->className->Out());
  this->toString->Add(buffer);
  
  this->toString->Add(COMMENT_SEPARATOR);
  this->toString->Add(COMMENT_SEPARATOR);
  
  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) {
    if (!strcmp(this->classAttributes->GetCurrent()->AttributeName()->Out(), "toString")) 
      continue;
    sprintf(buffer, "%s\n", this->classAttributes->GetCurrent()->GetAttributeSetMethodDeclaration(this->className)->Out());
    this->toString->Add(buffer);
    this->toString->Add(COMMENT_SEPARATOR);
    this->toString->Add(COMMENT_SEPARATOR);
  }
  
  this->toString->Add("\n");
  
  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) {
    if (!strcmp(this->classAttributes->GetCurrent()->AttributeName()->Out(), "toString")) 
      continue;
    sprintf(buffer, "%s\n", this->classAttributes->GetCurrent()->GetAttributeGetMethodDeclaration(this->className)->Out());
    this->toString->Add(buffer);
    this->toString->Add(COMMENT_SEPARATOR);
    this->toString->Add(COMMENT_SEPARATOR);
  }
  
  this->classMethods->SetInitial();
  while (this->classMethods->SetNext()) {
    sprintf(buffer, "%s\n", this->classMethods->GetCurrent()->GetMethodDeclaration(this->className)->Out());
    this->toString->Add(buffer);
    this->toString->Add(COMMENT_SEPARATOR);
    this->toString->Add(COMMENT_SEPARATOR);
  }
  
  sprintf(buffer, "%s %s::operator= (const %s& %c%s) {\n\n", this->className->Out(), this->className->Out(), this->className->Out(), tolower(this->className->Out()[0]), this->className->Out() + 1);
  this->toString->Add(buffer);
  
  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) {
    
    if (strstr(this->classAttributes->GetCurrent()->AttributeType()->Out(), "*")) {
      sprintf(format, "  *(this->%%-%ds) = *(%%c%%s.%%s);\n", lengthLargerAttributeType);
      sprintf(buffer, format, this->classAttributes->GetCurrent()->AttributeName()->Out(), tolower(this->className->Out()[0]), this->className->Out() + 1, this->classAttributes->GetCurrent()->AttributeName()->Out());
      this->toString->Add(buffer);
    }
    else {
      sprintf(format, "  this->%%-%ds = %%c%%s.%%s;\n", lengthLargerAttributeType);
      sprintf(buffer, format, this->classAttributes->GetCurrent()->AttributeName()->Out(), tolower(this->className->Out()[0]), this->className->Out() + 1, this->classAttributes->GetCurrent()->AttributeName()->Out());
      this->toString->Add(buffer);
    }
    
  }
  
  sprintf(buffer, "\n  return *this;\n", this->className->Out());
  this->toString->Add(buffer);

  sprintf(buffer, "\n}\n", this->className->Out());
  this->toString->Add(buffer);
  
  this->toString->Add(COMMENT_SEPARATOR);
  this->toString->Add(COMMENT_SEPARATOR);
  
  return this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool MakeCPPClass::ConstructListIncludes (TListE <String>* listIncludes) {
  
  if (!this->classAttributes || !this->classMethods)
    return false;
  
  this->classAttributes->SetInitial();
  while (this->classAttributes->SetNext()) {
    
    Attribute* currentAttribute = this->classAttributes->GetCurrent();
    
    currentAttribute->AttributeIncludes()->SetInitial();
    while (currentAttribute->AttributeIncludes()->SetNext()) 
      if (!listIncludes->FirstOcurrence(MakeClassSpace::EqualInclude, currentAttribute->AttributeIncludes()->GetCurrent()))
        listIncludes->Add(new String(*(currentAttribute->AttributeIncludes()->GetCurrent())));
    
  }
  
  this->classMethods->SetInitial();
  while (this->classMethods->SetNext()) {
    
    Method* currentMethod = this->classMethods->GetCurrent();
    
    currentMethod->MethodIncludes()->SetInitial();
    while (currentMethod->MethodIncludes()->SetNext())
      if (!listIncludes->FirstOcurrence(MakeClassSpace::EqualInclude, currentMethod->MethodIncludes()->GetCurrent()))
        listIncludes->Add(new String(*(currentMethod->MethodIncludes()->GetCurrent())));
    
  }
  
  listIncludes->QuickSortListByArray(MakeClassSpace::AscendentInclude, NULL);
  
  return true;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
MakeCPPClass MakeCPPClass::operator= (const MakeCPPClass& makeCPPClass) {
  
  this->className->In(makeCPPClass.className);
  
  *(this->classInheritance) = *(makeCPPClass.classInheritance);
  *(this->classAttributes)  = *(makeCPPClass.classAttributes);
  *(this->classMethods)     = *(makeCPPClass.classMethods);
  
  return *this;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
